import './multiSelect.scss';
import multiSelectTpl from './multiSelect.html';
import multiSelectController from './multiSelect.controller';

function multiSelectComponent($compile) {
  'ngInject';

  return {
    restrict: 'E',
    templateUrl: multiSelectTpl,
    scope: {
      msModel: '=',
      msOptions: '@',
    },
    compile(tElement, tAttrs) {
      /* eslint-disable max-len */
      const MS_OPTIONS_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?(?:\s+disable\s+when\s+([\s\S]+?))?\s+for\s+(?:([$\w][$\w]*)|(?:\(\s*([$\w][$\w]*)\s*,\s*([$\w][$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/;
      /* eslint-enable */
      const msOptionsExp = tAttrs.msOptions;
      let compiled1 = null;
      let compiled2 = null;
      let match = null;
      let matchResult = null;

      if (msOptionsExp) {
        match = msOptionsExp.match(MS_OPTIONS_REGEXP);
        if (!(match)) {
          throw 'got error msOptions';
        }
        matchResult = {
          value: match[1],
          label: match[2],
          collectionItem: match[5],
          collection: match[8],
        };

        const selectedItemLi = $(`<li class="ms-choice" ng-repeat="${matchResult.collectionItem} in $ctrl.selectedItems track by $index">
                                    <i class="icon iconfont icon-llalbumshopselectorcancel" ng-click="$ctrl.remove(${matchResult.collectionItem})"></i>
                                    <div ms-value="{{${matchResult.value}}}">{{${matchResult.label}}}</div>
                                  </li>`);
        const repeatLi = $(`<li class="ms-result ms-options"
                              ng-click="$ctrl.add(${matchResult.collectionItem})">
                              <div></div>
                            </li>`);
        repeatLi.attr('ng-repeat', `${matchResult.collectionItem} in $parent.${matchResult.collection}`);
        repeatLi.find('div').html(`{{${matchResult.label}}}`);
        compiled1 = $compile(selectedItemLi);
        compiled2 = $compile(repeatLi);
      }

      return function link(scope, iElement) {
        scope.$ctrl.msModel = scope.$ctrl.msModel || [];
        scope.$ctrl.selectedItems = [];

        if (scope.$ctrl.msOptions) {
          const selectedItemLis = compiled1(scope);
          const msRepeatLis = compiled2(scope);
          iElement.find('.ms-choices').prepend(selectedItemLis);
          iElement.find('.ms-reslut-container').append(msRepeatLis);

          scope.matchResult = matchResult;

          // danger error => sourceItem.id
          // msModel and source collection mapping
          // const mapModelToSource = (msModel, sourceCollection) {
          //   const selectedItems = [];
          //   msModel.forEach((modelItem) => {
          //     let one = sourceCollection.filter((sourceItem) => {
          //       if (sourceItem.id == modelItem) {
          //         return sourceItem;
          //       }
          //     });
          //   });
          // }
          // scope.$watch(`$parent[matchResult.collection]`, (newVal) => {
          //   if (newVal && newVal.length) {

          //   }
          // });
        }

        const $resultUl = iElement.find('.ms-reslut-container');
        const $ul = iElement.find('.ms-choices');
        const $input = $('#search-input');
        const ulWidth = $ul.width();
        const ulLeft = $ul.offset().left;

        // auto focus at search input when click ms-choices area
        $('.ms-choices').click((e) => {
          const $li = iElement.find('.ms-choice');
          const $target = $(e.target);

          if ($li.length && !$li.find($target).length) {
            const inputLeft = $input.offset().left;
            const width = ulWidth - (inputLeft - ulLeft);
            $input.css('width', `${width}px`);

            $input.focus();
          }
        });

        // clear key word and hide search result when input blur
        $input.blur((e) => {
          if (iElement.find('.ms-choice').length) {
            $input.css('width', '');
          }
          scope.$apply(() => {
            scope.$ctrl.view.keyword = '';
          });
          $resultUl.hide();
          $(e.relatedTarget).click();
        });

        $input.focus(() => {
          $resultUl.show();
        });

        // watch user list length
        scope.$watch('$ctrl.selectedItems', (newVal) => {
          if (newVal && newVal.length) {
            $input.removeClass('full');
          } else {
            $input.addClass('full');
          }
        }, true);

        // msModel and selectedItems two-way binding
        const findMapItemsByMsModel = () => {

        };

        // scope.$watch('$ctrl.msModel', (newVal) => {
        //   // const repeatCollection = scope.$parent[matchResult.collection];
        //   // const resultArr = repeatCollection.filter((sourceItem) => {
        //   //   newVal.forEach((newItem) => {
        //   //     if (angular.equals(newItem, sourceItem)) {
        //   //       return newItem;
        //   //     }
        //   //   })
        //   // });
        //   // scope.$ctrl.selectedItems = resultArr;
        // }, true);

        // scope.$watch('$ctrl.selectedItems', (newVal) => {
        //   // scope.$ctrl.msModel = newVal.map(item => item[]);
        // }, true);
      };
    },
    controller: multiSelectController,
    controllerAs: '$ctrl',
    bindToController: true,
    replace: true,
  };
}

export default multiSelectComponent;
